package com.xlhl.init.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xlhl.init.common.CustomHttpCode;
import com.xlhl.init.manage.MyBatisBatchManage;
import com.xlhl.init.mapper.RoleAssociationPermissionMapper;
import com.xlhl.init.mapper.RoleMapper;
import com.xlhl.init.model.dto.role.AddPermissionToRoleDTO;
import com.xlhl.init.model.entity.Permission;
import com.xlhl.init.model.entity.Role;
import com.xlhl.init.model.entity.RoleAssociationPermission;
import com.xlhl.init.service.PermissionService;
import com.xlhl.init.service.RoleAssociationPermissionService;
import com.xlhl.init.service.RoleService;
import com.xlhl.init.utils.AuthUtil;
import com.xlhl.init.utils.ThrowUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xlhl
 * @description 针对表【role(角色表(二进制权限控制))】的数据库操作Service实现
 * @createDate 2025-07-29 22:30:39
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role>
        implements RoleService {

    @Resource
    private RoleAssociationPermissionService associationPermissionService;

    @Resource
    private PermissionService permissionService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private MyBatisBatchManage myBatisBatchManage;

    /**
     * 为 角色 新增/修改权限
     *
     * @param dto
     * @return
     */
    @Override
    public boolean addPermissionToRole(AddPermissionToRoleDTO dto) {
        Long roleId = dto.getRoleId();
        List<Long> permissions = dto.getPermissions();
        //  多次修改数据库，添加事务管理
        Boolean executeRet = transactionTemplate.execute(status -> {
            //  先删除对应角色全部的权限信息
            associationPermissionService.remove(
                    new LambdaQueryWrapper<RoleAssociationPermission>().eq(RoleAssociationPermission::getRoleId, roleId)
            );

            boolean existsRet = this.lambdaQuery().eq(Role::getId, roleId).exists();
            ThrowUtil.throwIf(!existsRet, CustomHttpCode.NOT_FOUND_ERROR, "角色不存在");
            //  查询出需要操作的权限ID对应权限信息
            List<Permission> permissionList = permissionService.lambdaQuery()
                    .select(Permission::getId, Permission::getBitPosition, Permission::getFatherId)
                    .in(Permission::getId, permissions)
                    .list();
            Map<Long, Long> mainIdToBitPositionMap = new HashMap<>(permissionList.size());

            //  全新权限列表
            List<RoleAssociationPermission> newPermission = new ArrayList<>();

            //  遍历需要添加的权限，并且将其添加到对应主项之下
            for (Permission permission : permissionList) {
                Long mainId = permission.getFatherId();
                Integer bitPosition = permission.getBitPosition();
                if (!mainIdToBitPositionMap.containsKey(mainId)) {
                    mainIdToBitPositionMap.put(mainId, 0L);
                }

                mainIdToBitPositionMap.put(mainId, AuthUtil.addPermission(mainIdToBitPositionMap.get(mainId), bitPosition));
            }

            //  保存权限信息
            for (Long mainId : mainIdToBitPositionMap.keySet()) {
                //  但一个主项ID直接忽略掉
                if (mainId == -1) {
                    continue;
                }

                //  保存信息到新权限列表中
                RoleAssociationPermission permission = new RoleAssociationPermission();
                permission.setRoleId(roleId);
                permission.setPermissionMainId(mainId);
                permission.setPermission(mainIdToBitPositionMap.get(mainId));

                newPermission.add(permission);
            }
            //  使用批量插入节约资源
            myBatisBatchManage.batchInsert(newPermission, RoleAssociationPermissionMapper.class);
            return true;
        });

        return Boolean.TRUE.equals(executeRet);
    }
}




